home *** CD-ROM | disk | FTP | other *** search
/ PsL Monthly 1993 December / PSL Monthly Shareware CD-ROM (December 1993).iso / prgmming / dos / pascal / arith2.com / ARITH_DE.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1989-02-27  |  6.9 KB  |  250 lines

  1. UNIT arith_de;
  2.  
  3.         { ------------------------------------------------------------------
  4.  
  5.           This program and its associates implement in Turbo Pascal v5
  6.           the aritmetic encoding/decoding algorithms presented in the papers
  7.  
  8.           "Arithmetic Coding for Data Compression"
  9.  
  10.                    by Ian     H. Witten
  11.                       Radford M. Neal
  12.                       John    G. Cleary
  13.  
  14.           pp 520 - 540 of June 1987 Communications of the ACM
  15.  
  16.           and
  17.  
  18.           "An Adaptive Dependency Source Model For Data Compression"
  19.  
  20.                    by David M. Abrahamson
  21.  
  22.           pp 77 - 83 of January 1989 Communications of the ACM
  23.  
  24.           ------------------------------------------------------------------
  25.  
  26.           Implemented by Ken Westerback : CompuServe 73547,3520
  27.  
  28.           version 1.0 released 89/02/19
  29.           version 2.0 released 89/02/27
  30.  
  31.           These programs, units and associated documentation are released
  32.           into the public domain to be used and abused as your whims
  33.           dictate.
  34.  
  35.           Feel free to distribute/incorporate/improve as desired.
  36.  
  37.           >>>>> Use at your own risk! <<<<<
  38.  
  39.           Comments and suggestions welcome via CompuServe.
  40.  
  41.           ------------------------------------------------------------------
  42.         }
  43.  
  44.  
  45. INTERFACE uses dos;
  46.  
  47.  
  48. function start_decoding ( f_name : pathstr ) : char;
  49.  
  50. function decode_symbol ( var symbol : integer ) : boolean;
  51.  
  52. function done_decoding : longint;
  53.  
  54.  
  55. IMPLEMENTATION uses model_h, arith_h;
  56.  
  57.  
  58. var file_size, chars_to_read : longint;
  59.  
  60.  
  61. procedure read_big_buffer;
  62.           begin
  63.  
  64.           { try to read next bit_buffer }
  65.  
  66.           fillchar ( big_buffer, sizeof(big_buffer), 0 );
  67.  
  68.           if not eof ( bits_file ) then
  69.              begin
  70.  
  71.              if ( file_size < sizeof(big_buffer) ) then
  72.                 chars_to_read := file_size
  73.              else
  74.                 chars_to_read := sizeof(big_buffer);
  75.  
  76.              blockread ( bits_file, big_buffer, chars_to_read );
  77.  
  78.              dec ( file_size, chars_to_read );
  79.  
  80.              buffer_index := 0;
  81.              buffer       := big_buffer[ buffer_index ];
  82.              bits_to_go   := bits_per_buffer;
  83.  
  84.              end
  85.  
  86.           else { send up to code_value_bits arbitrary bits }
  87.              begin
  88.              if sending_crap then
  89.                 begin
  90.                 writeln ( 'decoding failed : bad input file' );
  91.                 halt;
  92.                 end
  93.              else
  94.                 begin
  95.                 sending_crap := true;
  96.                 buffer_index := 511;
  97.                 bits_to_go   := code_value_bits - 2;
  98.                 end;
  99.              end;
  100.  
  101.           end; { read big buffer }
  102.  
  103. function start_decoding ( f_name : pathstr ) : char;
  104.  
  105.           var     i : integer;
  106.               model : char;
  107.  
  108.           begin
  109.  
  110.           {I-}
  111.           Assign ( bits_file, f_name );
  112.           Reset ( bits_file, 1 );
  113.           {I+}
  114.  
  115.           if ioresult <> 0 then
  116.              begin
  117.              writeln;
  118.              writeln ( 'arith_de : error opening "', f_name, '"' );
  119.              writeln;
  120.              halt;
  121.              end;
  122.  
  123.           file_size := filesize ( bits_file ) - 1; { discount model byte }
  124.  
  125.           blockread ( bits_file, model, 1 );
  126.  
  127.           if not ( model in valid_models ) then
  128.              begin
  129.              writeln;
  130.              writeln ( 'arith_de : "', model, '" is not a valid model' );
  131.              writeln;
  132.              halt;
  133.              end;
  134.  
  135.           start_decoding := model;
  136.  
  137.           read_big_buffer;
  138.  
  139.           { input enough bits to initially fill the code value }
  140.  
  141.           for i := 1 to code_value_bits do
  142.               begin
  143.               value := value shl 1;
  144.               if odd ( buffer ) then inc ( value );
  145.               buffer := buffer shr 1;
  146.               inc ( bits_gotten );
  147.               dec ( bits_to_go );
  148.               end;
  149.  
  150.           end;
  151.  
  152. function decode_symbol ( var symbol : integer ) : boolean;
  153.  
  154.           var range : longint; { size of the current code region }
  155.               cum   : word;    { cumulative frequency calculated }
  156.               i     : integer;
  157.  
  158.           begin
  159.  
  160.           range := longint ( high - low ) + 1;
  161.  
  162.           { find the cumulative frequency for value }
  163.  
  164.           cum := ( ( longint(value) - low + 1 ) * cum_freq[ 0 ] - 1 ) div range;
  165.  
  166.           { then find the symbol }
  167.  
  168.           symbol := 1;
  169.           while ( cum_freq[ symbol ] > cum ) do inc ( symbol );
  170.  
  171.           if symbol = eof_symbol then decode_symbol := false
  172.           else                        decode_symbol := true;
  173.  
  174.           { narrow the code region to that alloted to this symbol }
  175.  
  176.           high := low + ( ( range * cum_freq[ symbol-1 ] ) div cum_freq[ 0 ] ) - 1;
  177.           low  := low +   ( range * cum_freq[ symbol   ] ) div cum_freq[ 0 ] ;
  178.  
  179.           { loop to get rid of bits }
  180.  
  181.           while true do
  182.                 begin
  183.  
  184.                 if      ( high < half ) then
  185.                    { do nothing = expand low half }
  186.  
  187.                 else if ( low >= half ) then
  188.                     { expand high half by subtracting offet to top }
  189.                     begin
  190.                     dec ( value, half );
  191.                     dec ( low,   half );
  192.                     dec ( high,  half );
  193.                     end
  194.  
  195.                 else if ( low >= first_qtr ) and ( high < third_qtr ) then
  196.                     { expand the middle half by subtracting the offset to middle }
  197.                     begin
  198.                     dec ( value, first_qtr );
  199.                     dec ( low,   first_qtr );
  200.                     dec ( high,  first_qtr );
  201.                     end
  202.  
  203.                 else exit; { all done so return to caller }
  204.  
  205.                 { scale up the code range & move in next bit }
  206.  
  207.                 low   := low shl 1;
  208.                 high  := ( high shl 1 )+ 1;
  209.  
  210.                 value := value shl 1;
  211.  
  212.                 if odd ( buffer ) then inc ( value );
  213.                 inc ( bits_gotten );
  214.  
  215.                 { update bit buffers }
  216.  
  217.                 dec ( bits_to_go );
  218.                 buffer := buffer shr 1;
  219.  
  220.                 if ( bits_to_go = 0 ) then
  221.                    begin
  222.  
  223.                    inc ( buffer_index );
  224.  
  225.                    if ( buffer_index = 512 ) then
  226.                       read_big_buffer
  227.  
  228.                    else
  229.                       { just get next word }
  230.                       begin
  231.                       buffer := big_buffer[ buffer_index ];
  232.                       bits_to_go := bits_per_buffer;
  233.                       end;
  234.  
  235.                    end;
  236.  
  237.                 end;
  238.  
  239.           end; { decode the next symbol }
  240.  
  241. function done_decoding : longint;
  242.           begin
  243.  
  244.           close ( bits_file );
  245.  
  246.           done_decoding := ( bits_gotten + 7 ) div 8;
  247.  
  248.           end; { done_decoding }
  249.  
  250. END. { arithmetic decoding implementation }